﻿using AutoMapper;
using CarparkBusiness;
using CarparkEnum;
using CarparkIMS_CMS.Infrastructure.Mapper;
using CarparkIMS_CMS.Models;
using CarparkIMS_Model;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using X.PagedList;

namespace CarparkIMS_CMS.Controllers
{
    public class JournalController : Controller
    {
        private readonly IMSContext _context;
        private readonly ILogger<JournalController> _logger;
        private ParkingSetting ParkingSetting { get; set; }

        public JournalController(IMSContext iMSContext, ILogger<JournalController> logger, IOptions<ParkingSetting> parkingSetting)
        {
            _context = iMSContext;
            this._logger = logger;
            if (ParkingSetting.Get() == null)
            {
                ParkingSetting = parkingSetting.Value ?? new ParkingSetting();
            }
            else
            {
                ParkingSetting = ParkingSetting.Get();
            }
        }

        [HttpGet]
        [Authorize(AuthenticationSchemes = Startup.AuthSchemes)]
        public async Task<IActionResult> Index(string searchString, DateTime? date)
        {
            var last3Months = DateTime.Now.AddMonths(-3);
            var today = DateTime.Now;
            DateTime dt = date ?? _context.llqqPlateLog.Max(l => (DateTime?)l.createdOn) ?? today;
            var nextDate = date?.AddDays(1);
            var query = _context.llqqPlateLog.Where(a => a.createdOn >= date && a.createdOn < nextDate && a.createdOn >= last3Months);
            //var query = _context.llqqPlateLog.Where(a => a.createdOn.Date >= dt.Date && a.createdOn >= last3Months);
            ViewBag.date = nextDate;

            if (!String.IsNullOrEmpty(searchString))
                query = query.Where(a => a.plate.Contains(searchString) || a.date.Contains(searchString) || a.ip.Contains(searchString));

            query = query.OrderByDescending(q => q.date);
            query = query.Take(2000);

            var result = await query.ToListAsync();
            var list = result.Select(a => new llqqPlateLogViewModel(a)).ToList();

            return View(list);
        }

        [Authorize(AuthenticationSchemes = Startup.AuthSchemes)]
        public IActionResult RealTime()
        {
            var today = DateTime.Now.Date;
            //today = new DateTime(2022, 07, 18);
            var records = _context.llqqPlateLog
                .Where(a => a.createdOn >= today && a.createdOn < today.AddDays(1))
                .OrderByDescending(a => a.date)
                .ThenByDescending(a => a.ID);

            var result = records.AsEnumerable().Select(a => new llqqPlateLogViewModel(a));

            return View(result);
        }

        [HttpGet]
        [Authorize(AuthenticationSchemes = Startup.AuthSchemes)]
        public IActionResult ParkingPlaceLog(string date, int? Page)
        {
            DateTime filterDate = DateTime.Now.AddMonths(-1).Date;
            if (!string.IsNullOrEmpty(date))
            {
                if (DateTime.TryParse(date, out DateTime date1))
                {
                    filterDate = date1;
                    ViewBag.Date = date1;
                }
            }

            long minSec = ParkingSetting.IntervalSeconds * ParkingSetting.MinTimesValid;
            ViewBag.MinSec = minSec;

            var query = _context.llqqNumberPlate.Where(a => a.CreatedOn.Date >= filterDate.Date);

            DateTime dateTimeNow = DateTime.Now.AddSeconds(-minSec);
            query = query.Where(a => a.CreatedOn < dateTimeNow).OrderByDescending(c => c.StartDatetime);

            if (Page.GetValueOrDefault() != 0)
            {
                Page = Page.GetValueOrDefault();
            }
            else
            {
                Page = 1;
            }

            ViewBag.Page = Page;

            try
            {
                var newItems = query.ToPagedList(Page.GetValueOrDefault(), 100);

                return View(newItems);
            }
            catch (Exception ex)
            {
                _logger.LogInformation(ex.Message);
                return View(query);
            }
        }

        [HttpGet]
        [Authorize(AuthenticationSchemes = Startup.AuthSchemes)]
        public IActionResult ParkingPlaceLog1(string date, int? Page)
        {
            DateTime filterDate = DateTime.Now.AddMonths(-1).Date;
            if (!string.IsNullOrEmpty(date))
            {
                if (DateTime.TryParse(date, out DateTime date1))
                {
                    filterDate = date1;
                    ViewBag.Date = date1;
                }
            }

            long minSec = 0; //ParkingSetting.IntervalSeconds * ParkingSetting.MinTimesValid;
            ViewBag.MinSec = minSec;

            var query = _context.llqqNumberPlate.Where(a => a.CreatedOn.Date >= filterDate.Date);
            DateTime dateTimeNow = DateTime.Now.AddSeconds(-minSec);
            query = query.Where(a => a.CreatedOn < dateTimeNow).OrderByDescending(c => c.StartDatetime);

            if (Page.GetValueOrDefault() != 0)
            {
                Page = Page.GetValueOrDefault();
            }
            else
            {
                Page = 1;
            }

            ViewBag.Page = Page;

            try
            {
                var newItems = query.ToPagedList(Page.GetValueOrDefault(), 100);

                return View(newItems);
            }
            catch (Exception ex)
            {
                _logger.LogInformation(ex.Message);
                return View(query);
            }
        }

        [HttpGet]
        [Authorize(AuthenticationSchemes = Startup.AuthSchemes)]
        public IActionResult ParkingStateList()
        {
            var query = _context.llqqCameraDoorMapping.ToList();

            List<CameraParkingModel> list = new List<CameraParkingModel>();

            foreach (var item in query)
            {
                CameraParkingModel cameraParkingModel = new CameraParkingModel
                {
                    llqqNumberPlate = GetRecnetlyllqqNumberPlate(item.ParkingPlaceId),
                    CameraIP = item.CameraIP,
                    ID = item.ID,
                    ParkingPlaceId = item.ParkingPlaceId,
                    Deleted = item.Deleted,
                    ParkingPlaceSharpNumber = item.ParkingPlaceSharpNumber
                };
                list.Add(cameraParkingModel);
            }

            return View(list);
        }

        [HttpGet]
        [Authorize(AuthenticationSchemes = Startup.AuthSchemes)]
        public IActionResult RefreshParkingState()
        {
            string[] args = new string[] { "", "" };
            ResponseModalX responseModalX = new ResponseModalX();

            responseModalX.meta = new MetaModalX { ErrorCode = -1, Success = true, Message = "SUCCESS" };

            Task task = Task.Run(() =>
            {
                //var services = new ServiceCollection();
                //TaskStartUp.ConfigureServices(services);
                //var serviceProvider = services.BuildServiceProvider();
                //ParkingSetting parkingSetting = serviceProvider.GetService<IOptions<ParkingSetting>>().Value;
                //CarParkingScheduleTask.RunTask(args, parkingSetting.IntervalMinutes).GetAwaiter();
                var services = new ServiceCollection();
                TaskStartUp.ConfigureServices(services);
                var serviceProvider = services.BuildServiceProvider();
                serviceProvider.GetService<MainCalcControlLer>().Run(args).GetAwaiter();
            });

            return Ok(responseModalX);
        }

        private llqqNumberPlate GetRecnetlyllqqNumberPlate(string parkingPlaceId)
        {
            llqqNumberPlate llqqNumberPlate = _context.llqqNumberPlate.Where(c => c.ParkingPlaceId.Equals(parkingPlaceId)).OrderByDescending(c => c.StartDatetime).FirstOrDefault();

            return llqqNumberPlate;
        }
    }
}
